'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var redux = require('redux');
var React = require('react');
var reselect = require('reselect');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n["default"] = e;
  return Object.freeze(n);
}

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var React__namespace = /*#__PURE__*/_interopNamespace(React);

function isLogicWrapper(logic) {
  return '_isKea' in logic;
}
function isBuiltLogic(logic) {
  return '_isKeaBuild' in logic;
}
var shallowCompare = function shallowCompare(obj1, obj2) {
  var keys1 = Object.keys(obj1);
  var keys2 = Object.keys(obj2);
  return keys1.length === keys2.length && keys1.every(function (key) {
    return obj2.hasOwnProperty(key) && obj1[key] === obj2[key];
  });
};

function _regeneratorRuntime() {
  _regeneratorRuntime = function () {
    return exports;
  };
  var exports = {},
    Op = Object.prototype,
    hasOwn = Op.hasOwnProperty,
    defineProperty = Object.defineProperty || function (obj, key, desc) {
      obj[key] = desc.value;
    },
    $Symbol = "function" == typeof Symbol ? Symbol : {},
    iteratorSymbol = $Symbol.iterator || "@@iterator",
    asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
    toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
  function define(obj, key, value) {
    return Object.defineProperty(obj, key, {
      value: value,
      enumerable: !0,
      configurable: !0,
      writable: !0
    }), obj[key];
  }
  try {
    define({}, "");
  } catch (err) {
    define = function (obj, key, value) {
      return obj[key] = value;
    };
  }
  function wrap(innerFn, outerFn, self, tryLocsList) {
    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
      generator = Object.create(protoGenerator.prototype),
      context = new Context(tryLocsList || []);
    return defineProperty(generator, "_invoke", {
      value: makeInvokeMethod(innerFn, self, context)
    }), generator;
  }
  function tryCatch(fn, obj, arg) {
    try {
      return {
        type: "normal",
        arg: fn.call(obj, arg)
      };
    } catch (err) {
      return {
        type: "throw",
        arg: err
      };
    }
  }
  exports.wrap = wrap;
  var ContinueSentinel = {};
  function Generator() {}
  function GeneratorFunction() {}
  function GeneratorFunctionPrototype() {}
  var IteratorPrototype = {};
  define(IteratorPrototype, iteratorSymbol, function () {
    return this;
  });
  var getProto = Object.getPrototypeOf,
    NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
  var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
  function defineIteratorMethods(prototype) {
    ["next", "throw", "return"].forEach(function (method) {
      define(prototype, method, function (arg) {
        return this._invoke(method, arg);
      });
    });
  }
  function AsyncIterator(generator, PromiseImpl) {
    function invoke(method, arg, resolve, reject) {
      var record = tryCatch(generator[method], generator, arg);
      if ("throw" !== record.type) {
        var result = record.arg,
          value = result.value;
        return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
          invoke("next", value, resolve, reject);
        }, function (err) {
          invoke("throw", err, resolve, reject);
        }) : PromiseImpl.resolve(value).then(function (unwrapped) {
          result.value = unwrapped, resolve(result);
        }, function (error) {
          return invoke("throw", error, resolve, reject);
        });
      }
      reject(record.arg);
    }
    var previousPromise;
    defineProperty(this, "_invoke", {
      value: function (method, arg) {
        function callInvokeWithMethodAndArg() {
          return new PromiseImpl(function (resolve, reject) {
            invoke(method, arg, resolve, reject);
          });
        }
        return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
      }
    });
  }
  function makeInvokeMethod(innerFn, self, context) {
    var state = "suspendedStart";
    return function (method, arg) {
      if ("executing" === state) throw new Error("Generator is already running");
      if ("completed" === state) {
        if ("throw" === method) throw arg;
        return doneResult();
      }
      for (context.method = method, context.arg = arg;;) {
        var delegate = context.delegate;
        if (delegate) {
          var delegateResult = maybeInvokeDelegate(delegate, context);
          if (delegateResult) {
            if (delegateResult === ContinueSentinel) continue;
            return delegateResult;
          }
        }
        if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
          if ("suspendedStart" === state) throw state = "completed", context.arg;
          context.dispatchException(context.arg);
        } else "return" === context.method && context.abrupt("return", context.arg);
        state = "executing";
        var record = tryCatch(innerFn, self, context);
        if ("normal" === record.type) {
          if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
          return {
            value: record.arg,
            done: context.done
          };
        }
        "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
      }
    };
  }
  function maybeInvokeDelegate(delegate, context) {
    var methodName = context.method,
      method = delegate.iterator[methodName];
    if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel;
    var record = tryCatch(method, delegate.iterator, context.arg);
    if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
    var info = record.arg;
    return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
  }
  function pushTryEntry(locs) {
    var entry = {
      tryLoc: locs[0]
    };
    1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
  }
  function resetTryEntry(entry) {
    var record = entry.completion || {};
    record.type = "normal", delete record.arg, entry.completion = record;
  }
  function Context(tryLocsList) {
    this.tryEntries = [{
      tryLoc: "root"
    }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
  }
  function values(iterable) {
    if (iterable) {
      var iteratorMethod = iterable[iteratorSymbol];
      if (iteratorMethod) return iteratorMethod.call(iterable);
      if ("function" == typeof iterable.next) return iterable;
      if (!isNaN(iterable.length)) {
        var i = -1,
          next = function next() {
            for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
            return next.value = undefined, next.done = !0, next;
          };
        return next.next = next;
      }
    }
    return {
      next: doneResult
    };
  }
  function doneResult() {
    return {
      value: undefined,
      done: !0
    };
  }
  return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", {
    value: GeneratorFunctionPrototype,
    configurable: !0
  }), defineProperty(GeneratorFunctionPrototype, "constructor", {
    value: GeneratorFunction,
    configurable: !0
  }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
    var ctor = "function" == typeof genFun && genFun.constructor;
    return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
  }, exports.mark = function (genFun) {
    return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
  }, exports.awrap = function (arg) {
    return {
      __await: arg
    };
  }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
    return this;
  }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
    void 0 === PromiseImpl && (PromiseImpl = Promise);
    var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
    return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
      return result.done ? result.value : iter.next();
    });
  }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
    return this;
  }), define(Gp, "toString", function () {
    return "[object Generator]";
  }), exports.keys = function (val) {
    var object = Object(val),
      keys = [];
    for (var key in object) keys.push(key);
    return keys.reverse(), function next() {
      for (; keys.length;) {
        var key = keys.pop();
        if (key in object) return next.value = key, next.done = !1, next;
      }
      return next.done = !0, next;
    };
  }, exports.values = values, Context.prototype = {
    constructor: Context,
    reset: function (skipTempReset) {
      if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
    },
    stop: function () {
      this.done = !0;
      var rootRecord = this.tryEntries[0].completion;
      if ("throw" === rootRecord.type) throw rootRecord.arg;
      return this.rval;
    },
    dispatchException: function (exception) {
      if (this.done) throw exception;
      var context = this;
      function handle(loc, caught) {
        return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
      }
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i],
          record = entry.completion;
        if ("root" === entry.tryLoc) return handle("end");
        if (entry.tryLoc <= this.prev) {
          var hasCatch = hasOwn.call(entry, "catchLoc"),
            hasFinally = hasOwn.call(entry, "finallyLoc");
          if (hasCatch && hasFinally) {
            if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
            if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
          } else if (hasCatch) {
            if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
          } else {
            if (!hasFinally) throw new Error("try statement without catch or finally");
            if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
          }
        }
      }
    },
    abrupt: function (type, arg) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
          var finallyEntry = entry;
          break;
        }
      }
      finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
      var record = finallyEntry ? finallyEntry.completion : {};
      return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
    },
    complete: function (record, afterLoc) {
      if ("throw" === record.type) throw record.arg;
      return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
    },
    finish: function (finallyLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
      }
    },
    catch: function (tryLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc === tryLoc) {
          var record = entry.completion;
          if ("throw" === record.type) {
            var thrown = record.arg;
            resetTryEntry(entry);
          }
          return thrown;
        }
      }
      throw new Error("illegal catch attempt");
    },
    delegateYield: function (iterable, resultName, nextLoc) {
      return this.delegate = {
        iterator: values(iterable),
        resultName: resultName,
        nextLoc: nextLoc
      }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
    }
  }, exports;
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  try {
    var info = gen[key](arg);
    var value = info.value;
  } catch (error) {
    reject(error);
    return;
  }
  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then(_next, _throw);
  }
}
function _asyncToGenerator(fn) {
  return function () {
    var self = this,
      args = arguments;
    return new Promise(function (resolve, reject) {
      var gen = fn.apply(self, args);
      function _next(value) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
      }
      function _throw(err) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
      }
      _next(undefined);
    });
  };
}
function _extends() {
  _extends = Object.assign ? Object.assign.bind() : function (target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i];
      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }
    return target;
  };
  return _extends.apply(this, arguments);
}
function _objectWithoutPropertiesLoose(source, excluded) {
  if (source == null) return {};
  var target = {};
  var sourceKeys = Object.keys(source);
  var key, i;
  for (i = 0; i < sourceKeys.length; i++) {
    key = sourceKeys[i];
    if (excluded.indexOf(key) >= 0) continue;
    target[key] = source[key];
  }
  return target;
}
function _unsupportedIterableToArray(o, minLen) {
  if (!o) return;
  if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === "Object" && o.constructor) n = o.constructor.name;
  if (n === "Map" || n === "Set") return Array.from(o);
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length;
  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
  return arr2;
}
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
  var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
  if (it) return (it = it.call(o)).next.bind(it);
  if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
    if (it) o = it;
    var i = 0;
    return function () {
      if (i >= o.length) return {
        done: true
      };
      return {
        done: false,
        value: o[i++]
      };
    };
  }
  throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

var reservedKeys = {
  key: true,
  path: true,
  pathString: true,
  props: true,
  inputs: true,
  wrapper: true,
  wrap: true,
  build: true,
  mount: true,
  unmount: true,
  isMounted: true,
  findMounted: true,
  extend: true
};
function activatePlugin(pluginToActivate) {
  var plugin = typeof pluginToActivate === 'function' ? pluginToActivate() : pluginToActivate;
  var _getContext = getContext(),
    plugins = _getContext.plugins;
  if (!plugin.name) {
    throw new Error('[KEA] Tried to activate a plugin without a name!');
  }
  if (plugins.activated.find(function (p) {
    return p.name === plugin.name;
  })) {
    throw new Error("[KEA] Tried to activate plugin \"" + plugin.name + "\", but it was already installed!");
  }
  plugins.activated.push(plugin);
  if (plugin.defaults) {
    var fields = Object.keys(typeof plugin.defaults === 'function' ? plugin.defaults() : plugin.defaults);
    for (var _i = 0, _fields = fields; _i < _fields.length; _i++) {
      var key = _fields[_i];
      if (plugins.logicFields[key] || reservedKeys[key]) {
        console.error("[KEA] Plugin \"" + plugin.name + "\" redefines logic field \"" + key + "\". Previously defined by " + (plugins.logicFields[key] || 'core'));
      }
      plugins.logicFields[key] = plugin.name;
    }
  }
  if (plugin.events) {
    for (var _i2 = 0, _Object$keys = Object.keys(plugin.events); _i2 < _Object$keys.length; _i2++) {
      var _key = _Object$keys[_i2];
      if (!plugins.events[_key]) {
        plugins.events[_key] = [];
      }
      plugins.events[_key].push(plugin.events[_key]);
    }
    plugin.events.afterPlugin && plugin.events.afterPlugin();
  }
}
function runPlugins(key) {
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key2 = 1; _key2 < _len; _key2++) {
    args[_key2 - 1] = arguments[_key2];
  }
  var _getContext2 = getContext(),
    plugins = _getContext2.plugins,
    debug = _getContext2.options.debug;
  if (debug) {
    var _console;
    (_console = console).log.apply(_console, ["[KEA] Event: " + key].concat(args));
  }
  if (plugins && plugins.events[key]) {
    plugins.events[key].forEach(function (pluginFunction) {
      pluginFunction.apply(void 0, args);
    });
  }
}

var ATTACH_REDUCER$1 = '@KEA/ATTACH_REDUCER';
var DETACH_REDUCER$1 = '@KEA/DETACH_REDUCER';
var defaultState = {};
function initRootReducerTree(pathStart) {
  var _getContext = getContext(),
    _getContext$reducers = _getContext.reducers,
    tree = _getContext$reducers.tree,
    whitelist = _getContext$reducers.whitelist;
  if (!tree[pathStart]) {
    if (whitelist && !whitelist[pathStart]) {
      throw new Error("[KEA] Can not start reducer's path with \"" + pathStart + "\"! Please add it to the whitelist");
    }
    tree[pathStart] = {};
    regenerateRootReducer(pathStart);
  }
}
function keaReducer(pathStart) {
  if (pathStart === void 0) {
    pathStart = 'scenes';
  }
  var _getContext2 = getContext(),
    roots = _getContext2.reducers.roots;
  initRootReducerTree(pathStart);
  return function (state, action, fullState) {
    if (state === void 0) {
      state = defaultState;
    }
    return roots[pathStart] ? roots[pathStart](state, action, fullState) : state;
  };
}
function attachReducer(logic) {
  var path = logic.path,
    reducer = logic.reducer;
  var _getContext3 = getContext(),
    tree = _getContext3.reducers.tree,
    attachStrategy = _getContext3.options.attachStrategy,
    store = _getContext3.store;
  var pathStart = path[0].toString();
  initRootReducerTree(pathStart);
  var pointer = tree;
  for (var i = 0; i < path.length; i++) {
    var pathPart = path[i].toString();
    if (i === path.length - 1) {
      if (pointer[pathPart]) {
        if (i === 0 && typeof pointer[pathPart] === 'object' && Object.keys(pointer[pathPart]).length === 0) ; else if (typeof pointer[pathPart] !== 'function') {
          console.error("[KEA] Can not add reducer to \"" + path.join('.') + "\". There is something in the way:", pointer[pathPart]);
          return;
        }
      }
      pointer[pathPart] = reducer;
    } else {
      if (!pointer[pathPart]) {
        pointer[pathPart] = {};
      }
      pointer = pointer[pathPart];
    }
  }
  regenerateRootReducer(pathStart);
  if (attachStrategy === 'dispatch' || attachStrategy === 'replace') {
    runPlugins('beforeAttach', logic);
    if (attachStrategy === 'dispatch') {
      store && store.dispatch({
        type: ATTACH_REDUCER$1,
        payload: {
          path: path,
          reducer: reducer
        }
      });
    } else if (attachStrategy === 'replace') {
      store && store.replaceReducer(createReduxStoreReducer());
    }
    runPlugins('afterAttach', logic);
  }
}
function detachReducer(logic) {
  var path = logic.path;
  var _getContext4 = getContext(),
    tree = _getContext4.reducers.tree,
    detachStrategy = _getContext4.options.detachStrategy,
    store = _getContext4.store;
  var pathStart = path[0].toString();
  if (detachStrategy === 'persist') {
    return;
  }
  var detached = false;
  for (var i = path.length - 2; i >= 0; i--) {
    var pointerToHere = tree;
    for (var j = 0; j <= i; j++) {
      pointerToHere = pointerToHere && pointerToHere[path[j].toString()] || undefined;
    }
    if (pointerToHere) {
      if (Object.keys(pointerToHere).length === 0) ; else if (Object.keys(pointerToHere).length >= 1 && i === path.length - 2 && typeof pointerToHere[path[i + 1].toString()] === 'function') {
        delete pointerToHere[path[i + 1].toString()];
        detached = true;
      } else if (detached && Object.keys(pointerToHere).length >= 1 && i < path.length - 2 && Object.keys(pointerToHere[path[i + 1].toString()]).length === 0) {
        delete pointerToHere[path[i + 1].toString()];
      } else {
        break;
      }
    }
  }
  regenerateRootReducer(pathStart);
  if (detached) {
    if (detachStrategy === 'dispatch' || detachStrategy === 'replace') {
      runPlugins('beforeDetach', logic);
      if (detachStrategy === 'dispatch') {
        store && store.dispatch({
          type: DETACH_REDUCER$1,
          payload: {
            path: path
          }
        });
      } else if (detachStrategy === 'replace') {
        store && store.replaceReducer(createReduxStoreReducer());
      }
      runPlugins('afterDetach', logic);
    }
  }
}
function regenerateRootReducer(pathStart) {
  var _getContext5 = getContext(),
    _getContext5$reducers = _getContext5.reducers,
    tree = _getContext5$reducers.tree,
    roots = _getContext5$reducers.roots,
    whitelist = _getContext5$reducers.whitelist;
  if (pathStart !== 'kea' && !whitelist && typeof tree[pathStart] === 'object' && Object.keys(tree[pathStart]).length === 0) {
    delete roots[pathStart];
  } else {
    roots[pathStart] = recursiveCreateReducer(tree[pathStart]);
  }
  regenerateCombinedReducer();
}
function recursiveCreateReducer(treeNode) {
  if (typeof treeNode === 'function') {
    return treeNode;
  }
  var children = {};
  Object.keys(treeNode).forEach(function (key) {
    if (typeof treeNode[key] !== 'undefined') {
      children[key] = recursiveCreateReducer(treeNode[key]);
    }
  });
  if (Object.keys(children).length > 0) {
    return combineKeaReducers(children);
  } else {
    var emptyObj = {};
    return function () {
      return emptyObj;
    };
  }
}
function combineKeaReducers(reducers) {
  return function combination(state, action, fullState) {
    if (state === void 0) {
      state = {};
    }
    var reducerKeys = Object.keys(reducers);
    var stateChanged = Object.keys(state).length !== reducerKeys.length;
    var nextState = {};
    for (var _i = 0, _reducerKeys = reducerKeys; _i < _reducerKeys.length; _i++) {
      var key = _reducerKeys[_i];
      var reducer = reducers[key];
      var previousKeyState = state[key];
      var nextKeyState = reducer(previousKeyState, action, fullState || state);
      if (typeof nextKeyState === 'undefined') {
        throw new Error("[KEA] Reducer \"" + key + "\" returned undefined for action \"" + (action && action.type) + "\"");
      }
      nextState[key] = nextKeyState;
      stateChanged = stateChanged || nextKeyState !== previousKeyState;
    }
    return stateChanged ? nextState : state;
  };
}
function regenerateCombinedReducer() {
  var _getContext$reducers2 = getContext().reducers,
    redux = _getContext$reducers2.redux,
    roots = _getContext$reducers2.roots;
  var reducers = _extends({}, redux, roots);
  getContext().reducers.combined = combineKeaReducers(reducers);
}
function createReduxStoreReducer() {
  regenerateCombinedReducer();
  return function (state, action) {
    var _getContext$reducers$, _getContext$reducers3;
    if (state === void 0) {
      state = defaultState;
    }
    return (_getContext$reducers$ = (_getContext$reducers3 = getContext().reducers).combined) === null || _getContext$reducers$ === void 0 ? void 0 : _getContext$reducers$.call(_getContext$reducers3, state, action, state);
  };
}

var shim = {exports: {}};

var useSyncExternalStoreShim_production_min = {};

var e = React__default["default"];
function h(a, b) { return a === b && (0 !== a || 1 / a === 1 / b) || a !== a && b !== b; }
var k = "function" === typeof Object.is ? Object.is : h, l = e.useState, m = e.useEffect, n = e.useLayoutEffect, p = e.useDebugValue;
function q(a, b) { var d = b(), f = l({ inst: { value: d, getSnapshot: b } }), c = f[0].inst, g = f[1]; n(function () { c.value = d; c.getSnapshot = b; r(c) && g({ inst: c }); }, [a, d, b]); m(function () { r(c) && g({ inst: c }); return a(function () { r(c) && g({ inst: c }); }); }, [a]); p(d); return d; }
function r(a) { var b = a.getSnapshot; a = a.value; try {
    var d = b();
    return !k(a, d);
}
catch (f) {
    return !0;
} }
function t(a, b) { return b(); }
var u = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? t : q;
useSyncExternalStoreShim_production_min.useSyncExternalStore = void 0 !== e.useSyncExternalStore ? e.useSyncExternalStore : u;

var useSyncExternalStoreShim_development = {};

if (process.env.NODE_ENV !== "production") {
    (function () {
        if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
            typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart ===
                'function') {
            __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
        }
        var React = React__default["default"];
        var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
        function error(format) {
            {
                {
                    for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
                        args[_key2 - 1] = arguments[_key2];
                    }
                    printWarning('error', format, args);
                }
            }
        }
        function printWarning(level, format, args) {
            {
                var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
                var stack = ReactDebugCurrentFrame.getStackAddendum();
                if (stack !== '') {
                    format += '%s';
                    args = args.concat([stack]);
                }
                var argsWithFormat = args.map(function (item) {
                    return String(item);
                });
                argsWithFormat.unshift('Warning: ' + format);
                Function.prototype.apply.call(console[level], console, argsWithFormat);
            }
        }
        function is(x, y) {
            return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y;
        }
        var objectIs = typeof Object.is === 'function' ? Object.is : is;
        var useState = React.useState, useEffect = React.useEffect, useLayoutEffect = React.useLayoutEffect, useDebugValue = React.useDebugValue;
        var didWarnOld18Alpha = false;
        var didWarnUncachedGetSnapshot = false;
        function useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
            {
                if (!didWarnOld18Alpha) {
                    if (React.startTransition !== undefined) {
                        didWarnOld18Alpha = true;
                        error('You are using an outdated, pre-release alpha of React 18 that ' + 'does not support useSyncExternalStore. The ' + 'use-sync-external-store shim will not work correctly. Upgrade ' + 'to a newer pre-release.');
                    }
                }
            }
            var value = getSnapshot();
            {
                if (!didWarnUncachedGetSnapshot) {
                    var cachedValue = getSnapshot();
                    if (!objectIs(value, cachedValue)) {
                        error('The result of getSnapshot should be cached to avoid an infinite loop');
                        didWarnUncachedGetSnapshot = true;
                    }
                }
            }
            var _useState = useState({
                inst: {
                    value: value,
                    getSnapshot: getSnapshot
                }
            }), inst = _useState[0].inst, forceUpdate = _useState[1];
            useLayoutEffect(function () {
                inst.value = value;
                inst.getSnapshot = getSnapshot;
                if (checkIfSnapshotChanged(inst)) {
                    forceUpdate({
                        inst: inst
                    });
                }
            }, [subscribe, value, getSnapshot]);
            useEffect(function () {
                if (checkIfSnapshotChanged(inst)) {
                    forceUpdate({
                        inst: inst
                    });
                }
                var handleStoreChange = function () {
                    if (checkIfSnapshotChanged(inst)) {
                        forceUpdate({
                            inst: inst
                        });
                    }
                };
                return subscribe(handleStoreChange);
            }, [subscribe]);
            useDebugValue(value);
            return value;
        }
        function checkIfSnapshotChanged(inst) {
            var latestGetSnapshot = inst.getSnapshot;
            var prevValue = inst.value;
            try {
                var nextValue = latestGetSnapshot();
                return !objectIs(prevValue, nextValue);
            }
            catch (error) {
                return true;
            }
        }
        function useSyncExternalStore$1(subscribe, getSnapshot, getServerSnapshot) {
            return getSnapshot();
        }
        var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
        var isServerEnvironment = !canUseDOM;
        var shim = isServerEnvironment ? useSyncExternalStore$1 : useSyncExternalStore;
        var useSyncExternalStore$2 = React.useSyncExternalStore !== undefined ? React.useSyncExternalStore : shim;
        useSyncExternalStoreShim_development.useSyncExternalStore = useSyncExternalStore$2;
        if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
            typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop ===
                'function') {
            __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
        }
    })();
}

if (process.env.NODE_ENV === 'production') {
    shim.exports = useSyncExternalStoreShim_production_min;
}
else {
    shim.exports = useSyncExternalStoreShim_development;
}

var pauseCounter = 0;
var isPaused = function isPaused() {
  return pauseCounter !== 0;
};
var getStoreState$1 = function getStoreState() {
  return getContext().store.getState();
};
function useSelector(selector) {
  return shim.exports.useSyncExternalStore(getContext().store.subscribe, function () {
    return selector(getStoreState$1());
  });
}
function useValues(logic) {
  var builtLogic = useMountedLogic(logic);
  return React.useMemo(function () {
    var response = {};
    var _loop = function _loop() {
      var key = _Object$keys[_i];
      Object.defineProperty(response, key, {
        get: function get() {
          return useSelector(builtLogic.selectors[key]);
        }
      });
    };
    for (var _i = 0, _Object$keys = Object.keys(builtLogic.selectors); _i < _Object$keys.length; _i++) {
      _loop();
    }
    return response;
  }, [builtLogic.pathString]);
}
function useAllValues(logic) {
  var builtLogic = useMountedLogic(logic);
  var response = {};
  for (var _i2 = 0, _Object$keys2 = Object.keys(builtLogic.selectors); _i2 < _Object$keys2.length; _i2++) {
    var key = _Object$keys2[_i2];
    response[key] = useSelector(builtLogic.selectors[key]);
  }
  return response;
}
function useActions(logic) {
  var builtLogic = useMountedLogic(logic);
  return builtLogic['actions'];
}
function useAsyncActions(logic) {
  var builtLogic = useMountedLogic(logic);
  return builtLogic['asyncActions'];
}
var blankContext = /*#__PURE__*/React.createContext(undefined);
function useMountedLogic(logic) {
  var builtLogicContext = isLogicWrapper(logic) ? getContext().react.contexts.get(logic) : null;
  var defaultBuiltLogic = React.useContext(builtLogicContext || blankContext);
  var builtLogic = isLogicWrapper(logic) ? defaultBuiltLogic || logic.build() : logic;
  var unmount = React.useRef(undefined);
  if (!unmount.current) {
    batchChanges(function () {
      unmount.current = builtLogic.mount();
    });
  }
  var pathString = React.useRef(builtLogic.pathString);
  if (pathString.current !== builtLogic.pathString) {
    batchChanges(function () {
      var _unmount$current;
      (_unmount$current = unmount.current) === null || _unmount$current === void 0 ? void 0 : _unmount$current.call(unmount);
      unmount.current = builtLogic.mount();
      pathString.current = builtLogic.pathString;
    });
  }
  React.useEffect(function useMountedLogicEffect() {
    if (!unmount.current) {
      batchChanges(function () {
        unmount.current = builtLogic.mount();
        pathString.current = builtLogic.pathString;
      });
    }
    return function useMountedLogicEffectCleanup() {
      batchChanges(function () {
        unmount.current && unmount.current();
        unmount.current = undefined;
      });
    };
  }, []);
  return builtLogic;
}
var timeout;
function batchChanges(callback) {
  var previousState = getStoreState$1();
  pauseCounter += 1;
  try {
    callback();
  } catch (e) {} finally {
    pauseCounter -= 1;
  }
  var newState = getStoreState$1();
  if (previousState !== newState) {
    timeout && clearTimeout(timeout);
    timeout = setTimeout(function () {
      return getContext().store.dispatch({
        type: '@KEA/FLUSH'
      });
    }, 0);
  }
}

var reduxDevToolsCompose = typeof window !== 'undefined' && window['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__'] ? window['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__'] : redux.compose;
var createDefaultOptions = function createDefaultOptions() {
  return {
    paths: [],
    reducers: {},
    preloadedState: undefined,
    middleware: [],
    compose: reduxDevToolsCompose,
    enhancers: [],
    plugins: []
  };
};
function createStore(opts) {
  if (opts === void 0) {
    opts = {};
  }
  var context = getContext();
  if (!context) {
    console.error('[KEA] Can not create a store without a Kea context.');
    return;
  }
  if (context['__store']) {
    console.error('[KEA] Already attached to a store! Exiting. Please reset the kea context before creating a store.');
    return;
  }
  var options = _extends({}, createDefaultOptions(), opts);
  context.reducers.redux = _extends({}, options.reducers);
  runPlugins('beforeReduxStore', options);
  if (options.middleware.length > 0) {
    options.enhancers = [redux.applyMiddleware.apply(void 0, options.middleware)].concat(options.enhancers);
  }
  var composeEnhancer = options.compose || redux.compose;
  var finalCreateStore = composeEnhancer.apply(void 0, [pauseListenersEnhancer].concat(options.enhancers))(redux.legacy_createStore);
  if (options.paths && options.paths.length > 0) {
    context.reducers.whitelist = {};
    options.paths.forEach(function (pathStart) {
      context.reducers.whitelist[pathStart] = true;
      initRootReducerTree(pathStart);
    });
  } else {
    initRootReducerTree('kea');
  }
  var store = finalCreateStore(createReduxStoreReducer(), _extends({}, options.preloadedState));
  context['__store'] = store;
  runPlugins('afterReduxStore', options, store);
  return store;
}
var pauseListenersEnhancer = function pauseListenersEnhancer(createStore) {
  return function (reducer, initialState) {
    var store = createStore(reducer, initialState);
    var storeSubscribe = store.subscribe;
    store.subscribe = function (observer) {
      var pausedObserver = function pausedObserver() {
        if (!isPaused()) {
          observer();
        }
      };
      return storeSubscribe(pausedObserver);
    };
    return store;
  };
};

var _excluded = ["plugins", "createStore", "defaults"];
var context;
function getContext() {
  return context;
}
var getStoreState = function getStoreState() {
  return getContext().store.getState();
};
function setContext(newContext) {
  context = newContext;
}
var contextId = 0;
function openContext(options, initial) {
  if (options === void 0) {
    options = {};
  }
  if (initial === void 0) {
    initial = false;
  }
  if (context) {
    console.error('[KEA] overwriting already opened context. This may lead to errors.');
  }
  var _options = options,
    plugins = _options.plugins,
    _options$createStore = _options.createStore,
    createStoreOptions = _options$createStore === void 0 ? true : _options$createStore,
    defaults = _options.defaults,
    otherOptions = _objectWithoutPropertiesLoose(_options, _excluded);
  var newContext = {
    contextId: "kea-context-" + contextId++,
    plugins: {
      activated: [],
      events: {},
      logicFields: {},
      contexts: {}
    },
    inputCounter: 0,
    reducerDefaults: defaults,
    wrapperContexts: new WeakMap(),
    buildHeap: [],
    mount: {
      counter: {},
      mounted: {}
    },
    react: {
      contexts: new WeakMap()
    },
    reducers: {
      tree: {},
      roots: {},
      redux: {},
      whitelist: false,
      combined: undefined
    },
    store: undefined,
    __store: undefined,
    options: _extends({
      debug: false,
      proxyFields: true,
      flatDefaults: false,
      attachStrategy: 'dispatch',
      detachStrategy: 'dispatch',
      defaultPath: ['kea', 'logic']
    }, otherOptions)
  };
  Object.defineProperty(newContext, 'store', {
    get: function get() {
      var store = newContext['__store'];
      if (!store && createStoreOptions) {
        return createStore(typeof createStoreOptions === 'object' ? createStoreOptions : {});
      }
      return store;
    },
    set: function set(store) {
      newContext['__store'] = store;
    }
  });
  setContext(newContext);
  activatePlugin(corePlugin);
  runPlugins('afterOpenContext', newContext, options);
  if (plugins) {
    for (var _iterator = _createForOfIteratorHelperLoose(plugins), _step; !(_step = _iterator()).done;) {
      var plugin = _step.value;
      activatePlugin(plugin);
    }
  }
  if (!initial && createStoreOptions) {
    context.store;
  }
  return context;
}
function closeContext() {
  if (context) {
    runPlugins('beforeCloseContext', context);
  }
  context = undefined;
}
function resetContext(options, initial) {
  if (options === void 0) {
    options = {};
  }
  if (initial === void 0) {
    initial = false;
  }
  if (context) {
    closeContext();
  }
  return openContext(options, initial);
}
function getPluginContext(name) {
  var _getContext = getContext(),
    plugins = _getContext.plugins;
  if (!plugins.contexts[name]) {
    plugins.contexts[name] = {};
  }
  return plugins.contexts[name];
}
function setPluginContext(name, pluginContext) {
  var _getContext2 = getContext(),
    plugins = _getContext2.plugins;
  plugins.contexts[name] = pluginContext;
}

function events(input) {
  return function (logic) {
    var events = typeof input === 'function' ? input(logic) : input;
    var _loop = function _loop() {
      var key = _Object$keys[_i];
      var event = events[key];
      var newEvent = Array.isArray(event) ? function (props, oldProps) {
        return event.forEach(function (e) {
          return e(props, oldProps);
        });
      } : event;
      if (logic.events[key]) {
        var oldEvent = logic.events[key];
        logic.events[key] = function (props, oldProps) {
          oldEvent === null || oldEvent === void 0 ? void 0 : oldEvent(props, oldProps);
          newEvent === null || newEvent === void 0 ? void 0 : newEvent(props, oldProps);
        };
      } else if (newEvent) {
        logic.events[key] = newEvent;
      }
    };
    for (var _i = 0, _Object$keys = Object.keys(events); _i < _Object$keys.length; _i++) {
      _loop();
    }
  };
}
function afterMount(input) {
  return events(function (logic) {
    return {
      afterMount: function afterMount() {
        return input(logic);
      }
    };
  });
}
function beforeUnmount(input) {
  return events(function (logic) {
    return {
      beforeUnmount: function beforeUnmount() {
        return input(logic);
      }
    };
  });
}
function propsChanged(input) {
  return events(function (logic) {
    return {
      propsChanged: function propsChanged(props, oldProps) {
        return input(logic, oldProps);
      }
    };
  });
}

var LISTENERS_BREAKPOINT = 'kea-listeners breakpoint broke';
var isBreakpoint = function isBreakpoint(error) {
  return error.message === LISTENERS_BREAKPOINT;
};
function listeners(input) {
  return function (logic) {
    var _logic$cache, _logic$cache$listener, _logic$cache2, _logic$cache2$listene;
    if (!logic.listeners) {
      logic.listeners = {};
      afterMount(function () {
        addListeners(logic);
      })(logic);
      beforeUnmount(function () {
        removeListeners(logic);
        if (logic.cache.listenerBreakpointCounter) {
          for (var _i = 0, _Object$keys = Object.keys(logic.cache.listenerBreakpointCounter); _i < _Object$keys.length; _i++) {
            var key = _Object$keys[_i];
            logic.cache.listenerBreakpointCounter[key] += 1;
          }
        }
      })(logic);
    }
    (_logic$cache$listener = (_logic$cache = logic.cache).listenerBreakpointCounter) !== null && _logic$cache$listener !== void 0 ? _logic$cache$listener : _logic$cache.listenerBreakpointCounter = {};
    (_logic$cache2$listene = (_logic$cache2 = logic.cache).listenerLastDispatchId) !== null && _logic$cache2$listene !== void 0 ? _logic$cache2$listene : _logic$cache2.listenerLastDispatchId = {};
    var listeners = typeof input === 'function' ? input(logic) : input;
    var _getContext = getContext(),
      contextId = _getContext.contextId;
    var _loop = function _loop() {
      var actionKey = _Object$keys2[_i2];
      var listenerArray = Array.isArray(listeners[actionKey]) ? listeners[actionKey] : [listeners[actionKey]];
      var key = actionKey;
      if (typeof logic.actions[key] !== 'undefined') {
        key = logic.actions[key].toString();
      }
      var start = logic.listeners[key] ? logic.listeners[key].length : 0;
      var listenerWrapperArray = listenerArray.map(function (listener, index) {
        var listenerKey = contextId + "/" + key + "/" + (start + index);
        return function (action, previousState) {
          var breakCounter = (logic.cache.listenerBreakpointCounter[listenerKey] || 0) + 1;
          logic.cache.listenerBreakpointCounter[listenerKey] = breakCounter;
          logic.cache.listenerLastDispatchId[listenerKey] = action.dispatchId;
          var throwIfCalled = function throwIfCalled() {
            if (logic.cache.listenerBreakpointCounter[listenerKey] !== breakCounter || contextId !== getContext().contextId) {
              var error = new Error(LISTENERS_BREAKPOINT);
              error.__keaDispatchId = logic.cache.listenerLastDispatchId[listenerKey];
              throw error;
            }
          };
          var breakpoint = function breakpoint(ms) {
            if (typeof ms !== 'undefined') {
              return new Promise(function (resolve) {
                return setTimeout(resolve, ms);
              }).then(function () {
                throwIfCalled();
              });
            } else {
              throwIfCalled();
            }
          };
          var response;
          try {
            response = listener(action.payload, breakpoint, action, previousState);
            if (response && response.then && typeof response.then === 'function') {
              trackPendingListener(logic, actionKey, response);
              if (action.dispatchId) {
                addDispatchListener(action.dispatchId, response);
              }
              return response["catch"](function (e) {
                if (e.message !== LISTENERS_BREAKPOINT) {
                  throw e;
                }
              })["finally"](function () {
                removeDispatchListener(action.dispatchId, response);
              });
            }
          } catch (e) {
            if (e.message !== LISTENERS_BREAKPOINT) {
              throw e;
            }
          }
          return response;
        };
      });
      if (logic.listeners[key]) {
        logic.listeners[key] = [].concat(logic.listeners[key], listenerWrapperArray);
      } else {
        logic.listeners[key] = listenerWrapperArray;
      }
    };
    for (var _i2 = 0, _Object$keys2 = Object.keys(listeners); _i2 < _Object$keys2.length; _i2++) {
      _loop();
    }
  };
}
function sharedListeners(input) {
  return function (logic) {
    logic.sharedListeners = _extends({}, logic.sharedListeners || {}, typeof input === 'function' ? input(logic) : input);
  };
}
function addListeners(logic) {
  var _logic$listeners;
  var _getPluginContext = getPluginContext('listeners'),
    byPath = _getPluginContext.byPath,
    byAction = _getPluginContext.byAction;
  byPath[logic.pathString] = (_logic$listeners = logic.listeners) !== null && _logic$listeners !== void 0 ? _logic$listeners : {};
  for (var _i3 = 0, _Object$entries = Object.entries((_logic$listeners2 = logic.listeners) !== null && _logic$listeners2 !== void 0 ? _logic$listeners2 : {}); _i3 < _Object$entries.length; _i3++) {
    var _logic$listeners2, _logic$actionTypes$ke;
    var _Object$entries$_i = _Object$entries[_i3],
      key = _Object$entries$_i[0],
      listenerArray = _Object$entries$_i[1];
    var type = (_logic$actionTypes$ke = logic.actionTypes[key]) !== null && _logic$actionTypes$ke !== void 0 ? _logic$actionTypes$ke : key;
    if (!byAction[type]) {
      byAction[type] = {};
    }
    byAction[type][logic.pathString] = listenerArray;
  }
}
function removeListeners(logic) {
  var _getPluginContext2 = getPluginContext('listeners'),
    byPath = _getPluginContext2.byPath,
    byAction = _getPluginContext2.byAction;
  for (var _i4 = 0, _Object$keys3 = Object.keys((_logic$listeners3 = logic.listeners) !== null && _logic$listeners3 !== void 0 ? _logic$listeners3 : {}); _i4 < _Object$keys3.length; _i4++) {
    var _logic$listeners3, _logic$actionTypes$ke2;
    var key = _Object$keys3[_i4];
    var type = (_logic$actionTypes$ke2 = logic.actionTypes[key]) !== null && _logic$actionTypes$ke2 !== void 0 ? _logic$actionTypes$ke2 : key;
    if (byAction[type]) {
      delete byAction[type][logic.pathString];
      if (Object.keys(byAction[type]).length === 0) {
        delete byAction[type];
      }
    }
  }
  delete byPath[logic.pathString];
}
function trackPendingListener(logic, actionKey, response) {
  var _getPluginContext3 = getPluginContext('listeners'),
    pendingPromises = _getPluginContext3.pendingPromises;
  pendingPromises.set(response, [logic, actionKey]);
  var remove = function remove() {
    pendingPromises["delete"](response);
  };
  response.then(remove)["catch"](remove);
}
function addDispatchListener(dispatchId, response) {
  var _getPluginContext4 = getPluginContext('listeners'),
    pendingDispatches = _getPluginContext4.pendingDispatches;
  var dispatches = pendingDispatches.get(dispatchId);
  if (dispatches) {
    dispatches.add(response);
  } else {
    pendingDispatches.set(dispatchId, new Set([response]));
  }
}
function removeDispatchListener(dispatchId, response) {
  var _getPluginContext5 = getPluginContext('listeners'),
    pendingDispatches = _getPluginContext5.pendingDispatches;
  var dispatches = pendingDispatches.get(dispatchId);
  if (dispatches) {
    dispatches["delete"](response);
    if (dispatches.size === 0) {
      pendingDispatches["delete"](dispatchId);
    }
  }
}

var asyncCounter = 0;
var nextDispatchId = function nextDispatchId() {
  return String(++asyncCounter);
};
function actions(input) {
  return function (logic) {
    var actions = typeof input === 'function' ? input(logic) : input;
    var _loop = function _loop() {
      var _Object$entries$_i = _Object$entries[_i],
        key = _Object$entries$_i[0],
        payloadCreator = _Object$entries$_i[1];
      var actionCreator = typeof payloadCreator === 'function' && '_isKeaAction' in payloadCreator ? payloadCreator : createActionCreator(createActionType(key, logic.pathString), payloadCreator !== null && payloadCreator !== void 0 ? payloadCreator : true);
      var type = actionCreator.toString();
      var _getContext = getContext(),
        disableAsyncActions = _getContext.options.disableAsyncActions;
      logic.actionCreators[key] = actionCreator;
      logic.actions[key] = function () {
        var builtAction = actionCreator.apply(void 0, arguments);
        getContext().store.dispatch(disableAsyncActions ? builtAction : _extends({}, builtAction, {
          dispatchId: nextDispatchId()
        }));
      };
      logic.actions[key].toString = function () {
        return type;
      };
      if (!disableAsyncActions) {
        logic.asyncActions[key] = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
          var builtAction,
            dispatchId,
            _getPluginContext,
            pendingDispatches,
            promises,
            responses,
            _args = arguments;
          return _regeneratorRuntime().wrap(function _callee$(_context) {
            while (1) {
              switch (_context.prev = _context.next) {
                case 0:
                  builtAction = actionCreator.apply(void 0, _args);
                  dispatchId = nextDispatchId();
                  getContext().store.dispatch(_extends({}, builtAction, {
                    dispatchId: dispatchId
                  }));
                  _getPluginContext = getPluginContext('listeners'), pendingDispatches = _getPluginContext.pendingDispatches;
                case 4:
                  promises = pendingDispatches.get(dispatchId);
                  if (promises) {
                    _context.next = 8;
                    break;
                  }
                  return _context.abrupt("return");
                case 8:
                  _context.prev = 8;
                  _context.next = 11;
                  return Promise.all(promises);
                case 11:
                  responses = _context.sent;
                  return _context.abrupt("return", responses[0]);
                case 15:
                  _context.prev = 15;
                  _context.t0 = _context["catch"](8);
                  if (!isBreakpoint(_context.t0)) {
                    _context.next = 21;
                    break;
                  }
                  if ('__keaDispatchId' in _context.t0) {
                    dispatchId = _context.t0.__keaDispatchId;
                  }
                  _context.next = 22;
                  break;
                case 21:
                  throw _context.t0;
                case 22:
                  _context.next = 4;
                  break;
                case 24:
                case "end":
                  return _context.stop();
              }
            }
          }, _callee, null, [[8, 15]]);
        }));
        logic.asyncActions[key].toString = function () {
          return type;
        };
      }
      logic.actionKeys[type] = key;
      logic.actionTypes[key] = type;
    };
    for (var _i = 0, _Object$entries = Object.entries(actions); _i < _Object$entries.length; _i++) {
      _loop();
    }
  };
}
function createActionCreator(type, payloadCreator) {
  var action = function action() {
    return {
      type: type,
      payload: typeof payloadCreator === 'function' ? payloadCreator.apply(void 0, arguments) : {
        value: true
      }
    };
  };
  action.toString = function () {
    return type;
  };
  action._isKeaAction = true;
  return action;
}
function createActionType(key, pathString) {
  var toSpaces = function toSpaces(key) {
    return key.replace(/(?:^|\.?)([A-Z])/g, function (x, y) {
      return ' ' + y.toLowerCase();
    }).replace(/^ /, '');
  };
  return toSpaces(key) + " (" + pathString + ")";
}

function connect(input) {
  return function (logic) {
    var props = logic.props || {};
    var connect = typeof input === 'function' ? input(props) : input;
    var connectLogic = Array.isArray(connect) ? connect : '_isKeaBuild' in connect || '_isKea' in connect ? [connect] : connect.logic;
    if (connectLogic) {
      for (var _iterator = _createForOfIteratorHelperLoose(connectLogic), _step; !(_step = _iterator()).done;) {
        var otherLogic = _step.value;
        if ('_isKea' in otherLogic) {
          otherLogic = otherLogic(props);
        }
        addConnection(logic, otherLogic);
      }
    }
    if ('_isKeaBuild' in connect || '_isKea' in connect || Array.isArray(connect)) {
      return;
    }
    if (connect.actions) {
      var response = deconstructMapping(connect.actions);
      var _loop = function _loop() {
        var _step2$value = _step2.value,
          otherLogic = _step2$value[0],
          from = _step2$value[1],
          to = _step2$value[2];
        if (typeof otherLogic !== 'function' && typeof otherLogic !== 'object') {
          throw new Error("[KEA] Logic \"" + logic.pathString + "\" can not connect to " + typeof otherLogic + " to request action \"" + from + "\"");
        }
        if (isLogicWrapper(otherLogic)) {
          otherLogic = otherLogic.build(props);
        }
        if (isBuiltLogic(otherLogic)) {
          addConnection(logic, otherLogic);
          if (getContext().buildHeap.includes(otherLogic)) {
            logic.actionCreators[to] = function () {
              var _otherLogic$actionCre;
              return (_otherLogic$actionCre = otherLogic.actionCreators)[from].apply(_otherLogic$actionCre, arguments);
            };
            logic.actionCreators[to].toString = function () {
              return createActionType(from, otherLogic.pathString);
            };
            logic.actionTypes[to] = logic.actionCreators[to].toString();
          } else {
            logic.actionCreators[to] = otherLogic.actionCreators[from];
            logic.actionTypes[to] = otherLogic.actionTypes[from];
          }
        } else {
          logic.actionCreators[to] = otherLogic[from];
          if (logic.actionCreators[to]._isKeaAction) {
            logic.actionTypes[to] = logic.actionCreators[to].toString();
          } else {
            logic.actionTypes[to] = logic.actionCreators[to]().type;
          }
        }
        logic.actionKeys[logic.actionTypes[to]] = to;
        if (typeof logic.actionCreators[to] === 'undefined') {
          throw new Error("[KEA] Logic \"" + logic.pathString + "\", connecting to action \"" + from + "\" returns 'undefined'");
        }
        logic.actions[to] = function () {
          var _logic$actionCreators;
          var builtAction = (_logic$actionCreators = logic.actionCreators)[to].apply(_logic$actionCreators, arguments);
          getContext().store.dispatch(builtAction);
        };
        logic.actions[to].toString = function () {
          return logic.actionTypes[to];
        };
      };
      for (var _iterator2 = _createForOfIteratorHelperLoose(response), _step2; !(_step2 = _iterator2()).done;) {
        _loop();
      }
    }
    if (connect.values) {
      var _response = deconstructMapping(connect.values);
      var _loop2 = function _loop2() {
        var _step3$value = _step3.value,
          otherLogic = _step3$value[0],
          from = _step3$value[1],
          to = _step3$value[2];
        if (typeof otherLogic !== 'function' && typeof otherLogic !== 'object') {
          throw new Error("[KEA] Logic \"" + logic.pathString + "\" can not connect to " + typeof otherLogic + " to request prop \"" + from + "\"");
        }
        if (isLogicWrapper(otherLogic)) {
          otherLogic = otherLogic(props);
        }
        if (isBuiltLogic(otherLogic)) {
          addConnection(logic, otherLogic);
          var selector = from === '*' ? otherLogic.selector : otherLogic.selectors[from];
          var throwError = function throwError() {
            throw new Error("Connected selector \"" + to + "\" on logic \"" + logic.pathString + "\" is undefined.");
          };
          if (selector) {
            logic.selectors[to] = selector;
          } else if (getContext().buildHeap.includes(otherLogic)) {
            logic.selectors[to] = function (state, props) {
              return otherLogic.selectors[from] ? otherLogic.selectors[from](state, props) : throwError();
            };
          } else {
            throwError();
          }
        } else if (typeof otherLogic === 'function') {
          logic.selectors[to] = from === '*' ? otherLogic : function (state, props) {
            var values = otherLogic(state, props);
            return values && values[from];
          };
        }
        if (logic.selectors[to] && !logic.values.hasOwnProperty(to)) {
          Object.defineProperty(logic.values, to, {
            get: function get() {
              return logic.selectors[to](getStoreState(), logic.props);
            },
            enumerable: true
          });
        }
      };
      for (var _iterator3 = _createForOfIteratorHelperLoose(_response), _step3; !(_step3 = _iterator3()).done;) {
        _loop2();
      }
    }
  };
}
function deconstructMapping(mapping) {
  if (mapping.length % 2 === 1) {
    console.error(mapping);
    throw new Error("[KEA] Uneven mapping given to connect");
  }
  var response = [];
  for (var i = 0; i < mapping.length; i += 2) {
    var logic = mapping[i];
    var array = mapping[i + 1];
    if (!Array.isArray(array)) {
      console.error(mapping);
      throw new Error('[KEA] Invalid mapping given to connect. Make sure every second element is an array!');
    }
    for (var j = 0; j < array.length; j++) {
      if (array[j].includes(' as ')) {
        var parts = array[j].split(' as ');
        response.push([logic, parts[0], parts[1]]);
      } else {
        response.push([logic, array[j], array[j]]);
      }
    }
  }
  return response;
}
function addConnection(logic, otherLogic) {
  if (!otherLogic.connections || Object.keys(otherLogic.connections).length === 0) {
    return;
  }
  if (logic.connections[otherLogic.pathString]) {
    return;
  }
  Object.keys(otherLogic.connections).forEach(function (path) {
    if (!logic.connections[path]) {
      logic.connections[path] = otherLogic.connections[path];
    }
  });
}

function defaults(input) {
  return function (logic) {
    var defaults = typeof input === 'function' ? input(logic) : input;
    if (typeof defaults === 'function') {
      logic.defaults['*'] = defaults;
    } else if (typeof defaults === 'object') {
      var contextDefaults = getContextDefaults(logic);
      for (var _i = 0, _Object$entries = Object.entries(defaults); _i < _Object$entries.length; _i++) {
        var _Object$entries$_i = _Object$entries[_i],
          key = _Object$entries$_i[0],
          value = _Object$entries$_i[1];
        logic.defaults[key] = contextDefaults && typeof contextDefaults[key] !== 'undefined' ? contextDefaults[key] : value;
      }
    } else {
      throw new Error("[KEA] Unknown defaults of type \"" + typeof defaults + "\" for logic \"" + logic.pathString + "\"");
    }
  };
}
function getContextDefaults(logic) {
  var _getContext = getContext(),
    reducerDefaults = _getContext.reducerDefaults;
  if (reducerDefaults && !('_keaAutomaticPath' in logic.path)) {
    if (getContext().options.flatDefaults) {
      if (reducerDefaults[logic.pathString]) {
        return reducerDefaults[logic.pathString];
      }
    } else {
      for (var _iterator = _createForOfIteratorHelperLoose(logic.path), _step; !(_step = _iterator()).done;) {
        var part = _step.value;
        reducerDefaults = reducerDefaults[part.toString()];
        if (typeof reducerDefaults !== 'object') {
          return;
        }
      }
      return reducerDefaults;
    }
  }
}

function selectors(input) {
  return function (logic) {
    var selectorInputs = typeof input === 'function' ? input(logic) : input;
    var builtSelectors = {};
    var _loop = function _loop() {
      var key = _Object$keys[_i];
      if (typeof logic.selectors[key] !== 'undefined') {
        throw new Error("[KEA] Logic \"" + logic.pathString + "\" selector \"" + key + "\" already exists");
      }
      addSelectorAndValue(logic, key, function () {
        return builtSelectors[key].apply(builtSelectors, arguments);
      });
    };
    for (var _i = 0, _Object$keys = Object.keys(selectorInputs); _i < _Object$keys.length; _i++) {
      _loop();
    }
    var propSelectors = typeof Proxy !== 'undefined' ? new Proxy(logic.props, {
      get: function get(target, prop) {
        if (!(prop in target)) {
          throw new Error("[KEA] Prop \"" + String(prop) + "\" not found for logic \"" + logic.pathString + "\". Attempted to use in a selector. Please specify a default via props({ " + String(prop) + ": '' }) to resolve.");
        }
        return function () {
          return target[prop];
        };
      }
    }) : Object.fromEntries(Object.keys(logic.props).map(function (key) {
      return [key, function () {
        return logic.props[key];
      }];
    }));
    var _loop2 = function _loop2() {
      var entry = _Object$entries[_i2];
      var key = entry[0],
        arr = entry[1];
      if (!arr) {
        throw new Error("[KEA] Logic \"" + logic.pathString + "\" selector \"" + key + "\" is undefined");
      }
      var input = arr[0],
        func = arr[1],
        memoizeOptions = arr[2];
      var args = input(logic.selectors, propSelectors);
      if (args.filter(function (a) {
        return typeof a !== 'function';
      }).length > 0) {
        var argTypes = args.map(function (a) {
          return typeof a;
        }).join(', ');
        var msg = "[KEA] Logic \"" + logic.pathString + "\", selector \"" + key + "\" has incorrect input: [" + argTypes + "].";
        throw new Error(msg);
      }
      builtSelectors[key] = reselect.createSelector(args, func, {
        memoizeOptions: memoizeOptions
      });
      addSelectorAndValue(logic, key, function (state, props) {
        if (state === void 0) {
          state = getStoreState();
        }
        if (props === void 0) {
          props = logic.props;
        }
        return builtSelectors[key](state, props);
      });
      if (!logic.values.hasOwnProperty(key)) {
        Object.defineProperty(logic.values, key, {
          get: function get() {
            return logic.selectors[key](getStoreState(), logic.props);
          },
          enumerable: true
        });
      }
    };
    for (var _i2 = 0, _Object$entries = Object.entries(selectorInputs); _i2 < _Object$entries.length; _i2++) {
      _loop2();
    }
  };
}
function addSelectorAndValue(logic, key, selector) {
  logic.selectors[key] = selector;
  if (!logic.values.hasOwnProperty(key)) {
    Object.defineProperty(logic.values, key, {
      get: function get() {
        return logic.selectors[key](getStoreState(), logic.props);
      },
      enumerable: true
    });
  }
}

function rootReducer() {
  return function (logic) {
    logic.reducer = function (state, action, fullState) {
      return combineKeaReducers(logic.reducers)(state, action, fullState);
    };
    if (!logic.selector) {
      rootSelector()(logic);
    }
  };
}
function rootSelector() {
  return function (logic) {
    logic.selector = function (state) {
      if (state === void 0) {
        state = getStoreState();
      }
      return pathSelector(logic.path, state);
    };
  };
}
function reducers(input) {
  return function (logic) {
    var reducers = typeof input === 'function' ? input(logic) : input;
    if (!logic.reducer) {
      rootReducer()(logic);
    }
    if (!logic.selector) {
      rootSelector()(logic);
    }
    var contextDefaults = getContextDefaults(logic);
    var _loop = function _loop() {
      var _logic$cache, _logic$cache$reducers, _logic$cache$reducers2, _logic$cache$reducers3;
      var _Object$entries$_i = _Object$entries[_i],
        key = _Object$entries$_i[0],
        object = _Object$entries$_i[1];
      var initialValue = void 0;
      var reducerOptions = void 0;
      var reducer = void 0;
      if (Array.isArray(object)) {
        var _object$, _object$Math$max;
        initialValue = (_object$ = object[0]) !== null && _object$ !== void 0 ? _object$ : null;
        reducer = (_object$Math$max = object[Math.max(1, object.length - 1)]) !== null && _object$Math$max !== void 0 ? _object$Math$max : {};
        if (object.length === 3) {
          reducerOptions = object[1];
        }
      } else if (typeof object === 'object') {
        initialValue = null;
        reducer = object;
      } else {
        throw new Error("[KEA] Logic \"" + logic.pathString + "\" reducer \"" + key + "\" is set to unsupported value");
      }
      if (reducerOptions) {
        var _logic$reducerOptions;
        logic.reducerOptions[key] = _extends({}, (_logic$reducerOptions = logic.reducerOptions[key]) !== null && _logic$reducerOptions !== void 0 ? _logic$reducerOptions : {}, reducerOptions);
      }
      if (typeof logic.defaults[key] === 'undefined') {
        if (contextDefaults && typeof contextDefaults[key] !== 'undefined') {
          logic.defaults[key] = contextDefaults[key];
        } else if (typeof logic.defaults['*'] === 'function') {
          logic.defaults[key] = function (state, props) {
            var v = logic.defaults['*'](state, props)[key];
            return typeof v === 'undefined' ? initialValue : typeof v === 'function' ? v(state, props) : v;
          };
        } else {
          logic.defaults[key] = initialValue;
        }
      }
      (_logic$cache$reducers = (_logic$cache = logic.cache).reducers) !== null && _logic$cache$reducers !== void 0 ? _logic$cache$reducers : _logic$cache.reducers = {};
      (_logic$cache$reducers3 = (_logic$cache$reducers2 = logic.cache.reducers)[key]) !== null && _logic$cache$reducers3 !== void 0 ? _logic$cache$reducers3 : _logic$cache$reducers2[key] = {};
      var mapping = logic.cache.reducers[key];
      for (var _i2 = 0, _Object$keys = Object.keys((_reducer = reducer) !== null && _reducer !== void 0 ? _reducer : {}); _i2 < _Object$keys.length; _i2++) {
        var _reducer;
        var _key = _Object$keys[_i2];
        var mappingKey = logic.actions[_key] ? logic.actions[_key].toString() : _key;
        mapping[mappingKey] = reducer[_key];
      }
      if (typeof mapping['undefined'] !== 'undefined' && typeof logic.actions['undefined'] === 'undefined') {
        throw new Error("[KEA] Logic \"" + logic.pathString + "\" reducer \"" + key + "\" is waiting for an action that is undefined: [" + Object.keys(mapping).join(', ') + "]");
      }
      if (!logic.reducers[key] && logic.selectors[key]) {
        throw new Error("[KEA] Logic \"" + logic.pathString + "\" can't add reducer \"" + key + "\" because a selector with the same name exists.");
      }
      if (Object.keys(mapping).length === 0) {
        logic.reducers[key] = function () {
          return logic.defaults[key];
        };
      } else {
        logic.reducers[key] = function (state, action, fullState) {
          if (typeof state === 'undefined') {
            state = getDefaultState(logic.defaults[key], fullState, key, logic);
          }
          if (mapping[action.type]) {
            return mapping[action.type](state, action.payload, action.meta);
          } else if (logic.actionKeys[action.type] && mapping[logic.actionKeys[action.type]]) {
            return mapping[logic.actionKeys[action.type]](state, action.payload, action.meta);
          } else {
            return state;
          }
        };
      }
      if (!logic.selectors[key]) {
        addSelectorAndValue(logic, key, reselect.createSelector(logic.selector, function (state) {
          return state[key];
        }));
      }
    };
    for (var _i = 0, _Object$entries = Object.entries(reducers); _i < _Object$entries.length; _i++) {
      _loop();
    }
  };
}
function getDefaultState(defaultValue, fullState, key, logic) {
  if (typeof defaultValue === 'function') {
    if (fullState) {
      return defaultValue(fullState, logic.props);
    } else {
      console.error("[KEA] Store not initialized and can't get default value of \"" + key + "\" in \"" + logic.pathString + "\"");
      return undefined;
    }
  }
  return defaultValue;
}
function pathSelector(path, state) {
  return [state].concat(path).reduce(function (v, a) {
    if (a in v) {
      return v[a];
    }
    throw new Error("[KEA] Can not find path \"" + path.join('.') + "\" in the store.");
  });
}

function key(input) {
  return function (logic) {
    var key = input(logic.props);
    if (typeof logic.keyBuilder !== 'undefined') {
      throw new Error("[KEA] Already defined key builder for logic \"" + logic.pathString + "\".");
    }
    if (typeof key === 'undefined') {
      throw new Error("[KEA] Undefined key for logic \"" + logic.pathString + "\"");
    }
    if (Object.keys(logic.actions).length > 0) {
      throw new Error("[KEA] Can not add key to logic \"" + logic.pathString + "\" after adding actions: " + Object.keys(logic.actions).join(', '));
    }
    logic.key = key;
    logic.keyBuilder = input;
    var isAutomaticPath = ('_keaAutomaticPath' in logic.path);
    logic.path = [].concat(logic.path, [logic.key]);
    logic.pathString = logic.path.join('.');
    if (isAutomaticPath) {
      logic.path['_keaAutomaticPath'] = true;
    }
  };
}

function props(input) {
  return function (logic) {
    var newProps = _extends({}, input, logic.props);
    if (!shallowCompare(logic.props, newProps)) {
      logic.lastProps = newProps;
      Object.assign(logic.props, newProps);
    }
  };
}

function path(input) {
  return function (logic) {
    if (logic.path && !('_keaAutomaticPath' in logic.path)) {
      return;
    }
    if (Object.keys(logic.actions).length > 0) {
      throw new Error("[KEA] Can not add path to logic \"" + logic.pathString + "\" after adding actions: " + Object.keys(logic.actions).join(', '));
    }
    if (typeof input === 'function') {
      logic.path = input(logic.key).filter(function (l) {
        return typeof l !== 'undefined';
      });
    } else {
      logic.path = typeof logic.key !== 'undefined' ? [].concat(input, [logic.key]) : input;
    }
    logic.pathString = logic.path.join('.');
  };
}

var corePlugin = {
  name: 'core',
  defaults: function defaults() {
    return {
      actionCreators: {},
      actionKeys: {},
      actionTypes: {},
      actions: {},
      asyncActions: {},
      cache: {},
      connections: {},
      defaults: {},
      listeners: undefined,
      reducers: {},
      reducer: undefined,
      reducerOptions: {},
      selector: undefined,
      selectors: {},
      sharedListeners: undefined,
      values: {},
      events: {}
    };
  },
  events: {
    afterPlugin: function afterPlugin() {
      setPluginContext('listeners', {
        byAction: {},
        byPath: {},
        pendingPromises: new Map(),
        pendingDispatches: new Map()
      });
    },
    beforeReduxStore: function beforeReduxStore(options) {
      options.middleware.push(function (store) {
        return function (next) {
          return function (action) {
            var previousState = store.getState();
            var response = next(action);
            var _getPluginContext = getPluginContext('listeners'),
              byAction = _getPluginContext.byAction;
            var listeners = byAction[action.type];
            if (listeners) {
              for (var _i = 0, _Object$values = Object.values(listeners); _i < _Object$values.length; _i++) {
                var listenerArray = _Object$values[_i];
                for (var _iterator = _createForOfIteratorHelperLoose(listenerArray), _step; !(_step = _iterator()).done;) {
                  var innerListener = _step.value;
                  innerListener(action, previousState);
                }
              }
            }
            return response;
          };
        };
      });
    },
    legacyBuild: function legacyBuild(logic, input) {
      'connect' in input && input.connect && connect(input.connect)(logic);
      runPlugins('legacyBuildAfterConnect', logic, input);
      'actions' in input && input.actions && actions(input.actions)(logic);
      'defaults' in input && input.defaults && defaults(input.defaults)(logic);
      runPlugins('legacyBuildAfterDefaults', logic, input);
      'reducers' in input && input.reducers && reducers(input.reducers)(logic);
      'selectors' in input && input.selectors && selectors(input.selectors)(logic);
      'sharedListeners' in input && sharedListeners(input.sharedListeners)(logic);
      'listeners' in input && input.listeners && listeners(input.listeners)(logic);
      'events' in input && input.events && events(input.events)(logic);
    }
  }
};

function mountLogic(logic, count) {
  if (count === void 0) {
    count = 1;
  }
  var _getContext = getContext(),
    _getContext$mount = _getContext.mount,
    counter = _getContext$mount.counter,
    mounted = _getContext$mount.mounted;
  var pathStrings = Object.keys(logic.connections).filter(function (k) {
    return k !== logic.pathString;
  }).concat([logic.pathString]);
  for (var _iterator = _createForOfIteratorHelperLoose(pathStrings), _step; !(_step = _iterator()).done;) {
    var pathString = _step.value;
    counter[pathString] = (counter[pathString] || 0) + count;
    if (counter[pathString] === count) {
      var _connectedLogic$event, _connectedLogic$event2, _connectedLogic$event3, _connectedLogic$event4;
      var connectedLogic = logic.connections[pathString];
      if (typeof connectedLogic === 'undefined') {
        throw new Error("[KEA] Can not find connected logic at \"" + pathString + "\". Got \"undefined\" instead of the logic when trying to mount \"" + logic.pathString + "\".");
      }
      runPlugins('beforeMount', connectedLogic);
      (_connectedLogic$event = (_connectedLogic$event2 = connectedLogic.events).beforeMount) === null || _connectedLogic$event === void 0 ? void 0 : _connectedLogic$event.call(_connectedLogic$event2);
      mounted[pathString] = connectedLogic;
      if (connectedLogic.reducer) {
        attachReducer(connectedLogic);
      }
      runPlugins('afterMount', connectedLogic);
      (_connectedLogic$event3 = (_connectedLogic$event4 = connectedLogic.events).afterMount) === null || _connectedLogic$event3 === void 0 ? void 0 : _connectedLogic$event3.call(_connectedLogic$event4);
    }
  }
}
function unmountLogic(logic) {
  var _getContext2 = getContext(),
    _getContext2$mount = _getContext2.mount,
    counter = _getContext2$mount.counter,
    mounted = _getContext2$mount.mounted;
  var pathStrings = Object.keys(logic.connections).filter(function (k) {
    return k !== logic.pathString;
  }).concat([logic.pathString]).reverse();
  for (var _iterator2 = _createForOfIteratorHelperLoose(pathStrings), _step2; !(_step2 = _iterator2()).done;) {
    var pathString = _step2.value;
    counter[pathString] = (counter[pathString] || 0) - 1;
    if (counter[pathString] === 0) {
      var _connectedLogic$event5, _connectedLogic$event6, _connectedLogic$event7, _connectedLogic$event8, _getContext$wrapperCo;
      var connectedLogic = logic.connections[pathString];
      runPlugins('beforeUnmount', connectedLogic);
      (_connectedLogic$event5 = (_connectedLogic$event6 = connectedLogic.events).beforeUnmount) === null || _connectedLogic$event5 === void 0 ? void 0 : _connectedLogic$event5.call(_connectedLogic$event6);
      delete mounted[pathString];
      delete counter[pathString];
      if (connectedLogic.reducer) {
        detachReducer(connectedLogic);
      }
      runPlugins('afterUnmount', connectedLogic);
      (_connectedLogic$event7 = (_connectedLogic$event8 = connectedLogic.events).afterUnmount) === null || _connectedLogic$event7 === void 0 ? void 0 : _connectedLogic$event7.call(_connectedLogic$event8);
      (_getContext$wrapperCo = getContext().wrapperContexts.get(logic.wrapper)) === null || _getContext$wrapperCo === void 0 ? void 0 : _getContext$wrapperCo.builtLogics["delete"](logic.key);
    }
  }
}

function applyInputToLogic(logic, input) {
  runPlugins('beforeLogic', logic, input);
  if (typeof input === 'function') {
    input(logic);
  } else {
    'props' in input && props(input.props)(logic);
    'key' in input && typeof input.key !== 'undefined' && key(input.key)(logic);
    'path' in input && input.path && path(input.path)(logic);
    if (input.inherit) {
      for (var _iterator = _createForOfIteratorHelperLoose(input.inherit), _step; !(_step = _iterator()).done;) {
        var inheritLogic = _step.value;
        for (var _iterator2 = _createForOfIteratorHelperLoose(inheritLogic.inputs), _step2; !(_step2 = _iterator2()).done;) {
          var inheritInput = _step2.value;
          applyInputToLogic(logic, inheritInput);
        }
      }
    }
    runPlugins('legacyBuild', logic, input);
    if (input.extend) {
      for (var _iterator3 = _createForOfIteratorHelperLoose(input.extend), _step3; !(_step3 = _iterator3()).done;) {
        var innerInput = _step3.value;
        applyInputToLogic(logic, innerInput);
      }
    }
  }
  runPlugins('afterLogic', logic, input);
  return logic;
}
function getBuiltLogic(wrapper, props) {
  var wrapperContext = getWrapperContext(wrapper);
  if (wrapperContext.isBuilding) {
    throw new Error("[KEA] Circular build detected.");
  }
  var cachedLogic = getCachedBuiltLogicByProps(wrapper, props);
  if (cachedLogic) {
    var prevPropsClone = null;
    if (props && (!cachedLogic.props || cachedLogic.lastProps !== props && (!shallowCompare(cachedLogic.lastProps, props) || !shallowCompare(cachedLogic.props, _extends({}, cachedLogic.props, props))))) {
      prevPropsClone = _extends({}, cachedLogic.props);
      Object.assign(cachedLogic.props, props);
      cachedLogic.lastProps = props;
    }
    if (prevPropsClone && cachedLogic.events.propsChanged) {
      var newPropsClone = _extends({}, cachedLogic.props);
      batchChanges(function () {
        var _cachedLogic$events$p, _cachedLogic$events;
        (_cachedLogic$events$p = (_cachedLogic$events = cachedLogic.events).propsChanged) === null || _cachedLogic$events$p === void 0 ? void 0 : _cachedLogic$events$p.call(_cachedLogic$events, newPropsClone, prevPropsClone);
      });
    }
    return cachedLogic;
  }
  var uniqueId = ++getContext().inputCounter;
  var path = [].concat(getContext().options.defaultPath, [uniqueId]);
  path['_keaAutomaticPath'] = true;
  wrapperContext.isBuilding = true;
  var logic = {
    _isKeaBuild: true,
    key: undefined,
    keyBuilder: undefined,
    path: path,
    pathString: path.join('.'),
    props: _extends({}, props),
    lastProps: props !== null && props !== void 0 ? props : {},
    wrapper: wrapper,
    extend: function extend(input) {
      return applyInputToLogic(logic, input);
    },
    mount: function mount() {
      if (wrapperContext.isBuilding) {
        throw new Error("[KEA] Tried to mount logic \"" + logic.pathString + "\" before it finished building");
      }
      mountLogic(logic);
      var unmounted = false;
      return function () {
        if (unmounted) {
          throw new Error("[KEA] Tried to unmount logic \"" + logic.pathString + "\" for a second time");
        }
        unmountLogic(logic);
        unmounted = true;
      };
    },
    unmount: function unmount() {
      return unmountLogic(logic);
    },
    isMounted: function isMounted() {
      var counter = getContext().mount.counter[logic.pathString];
      return typeof counter === 'number' && counter > 0;
    }
  };
  var _getContext = getContext(),
    buildHeap = _getContext.buildHeap;
  try {
    buildHeap.push(logic);
    for (var _iterator4 = _createForOfIteratorHelperLoose(getContext().plugins.activated), _step4; !(_step4 = _iterator4()).done;) {
      var plugin = _step4.value;
      if (plugin.defaults) {
        var newLogicProperties = typeof plugin.defaults === 'function' ? plugin.defaults() : plugin.defaults;
        Object.assign(logic, newLogicProperties);
      }
    }
    runPlugins('beforeBuild', logic, wrapper.inputs);
    for (var _iterator5 = _createForOfIteratorHelperLoose(wrapper.inputs), _step5; !(_step5 = _iterator5()).done;) {
      var input = _step5.value;
      applyInputToLogic(logic, input);
    }
    logic.connections[logic.pathString] = logic;
    wrapperContext.keyBuilder = logic.keyBuilder;
    wrapperContext.builtLogics.set(logic.key, logic);
    runPlugins('afterBuild', logic, wrapper.inputs);
  } catch (e) {
    throw e;
  } finally {
    wrapperContext.isBuilding = false;
    buildHeap.pop();
  }
  if (buildHeap.length > 0) {
    if (!buildHeap[buildHeap.length - 1].connections[logic.pathString]) {
      addConnection(buildHeap[buildHeap.length - 1], logic);
    }
  }
  return logic;
}
function getCachedBuiltLogicByKey(wrapper, key) {
  var wrapperContext = getWrapperContext(wrapper);
  var builtLogic = wrapperContext.builtLogics.get(key);
  return builtLogic !== null && builtLogic !== void 0 ? builtLogic : null;
}
function getCachedBuiltLogicByProps(wrapper, props) {
  var _wrapperContext$keyBu;
  var wrapperContext = getWrapperContext(wrapper);
  return getCachedBuiltLogicByKey(wrapper, wrapperContext === null || wrapperContext === void 0 ? void 0 : (_wrapperContext$keyBu = wrapperContext.keyBuilder) === null || _wrapperContext$keyBu === void 0 ? void 0 : _wrapperContext$keyBu.call(wrapperContext, props !== null && props !== void 0 ? props : {}));
}
function getWrapperContext(wrapper) {
  var _getContext2 = getContext(),
    wrapperContexts = _getContext2.wrapperContexts;
  var wrapperContext = wrapperContexts.get(wrapper);
  if (!wrapperContext) {
    wrapperContext = {
      keyBuilder: undefined,
      builtLogics: new Map(),
      isBuilding: false
    };
    wrapperContexts.set(wrapper, wrapperContext);
  }
  return wrapperContext;
}

function wrapComponent(Component, wrapper) {
  runPlugins('beforeWrap', wrapper, Component);
  injectActionsIntoClass(Component);
  var Kea = function Kea(props) {
    var _props$actions;
    var logic = wrapper.build(props);
    var values = useAllValues(logic);
    var actions = _extends({}, (_props$actions = props.actions) !== null && _props$actions !== void 0 ? _props$actions : {}, useActions(logic));
    runPlugins('beforeRender', logic, props);
    return /*#__PURE__*/React__namespace.createElement(Component, _extends({}, props, values, {
      dispatch: getContext().store.dispatch,
      actions: actions
    }));
  };
  Kea._wrapper = wrapper;
  Kea._wrappedComponent = Component;
  runPlugins('afterWrap', wrapper, Component, Kea);
  return Kea;
}
function injectActionsIntoClass(Component) {
  function isStateless(Component) {
    return typeof Component === 'function' && !(Component.prototype && Component.prototype.isReactComponent);
  }
  if (!isStateless(Component)) {
    if (!Object.getOwnPropertyDescriptor(Component.prototype, 'actions')) {
      Object.defineProperty(Component.prototype, 'actions', {
        get: function actions() {
          return this.props.actions;
        }
      });
    }
  }
}

function kea(input) {
  var wrapper = function wrapper(props) {
    if (typeof props === 'object' || typeof props === 'undefined') {
      return wrapper.build(props);
    }
    return wrapper.wrap(props);
  };
  wrapper._isKea = true;
  wrapper.inputs = Array.isArray(input) ? input : [input];
  wrapper.wrap = function (Component) {
    return wrapComponent(Component, wrapper);
  };
  wrapper.build = function (props) {
    return getBuiltLogic(wrapper, props);
  };
  wrapper.mount = function () {
    return wrapper.build().mount();
  };
  wrapper.unmount = function () {
    return wrapper.build().unmount();
  };
  wrapper.isMounted = function (keyOrProps) {
    return !!wrapper.findMounted(keyOrProps);
  };
  wrapper.findMounted = function (keyOrProps) {
    try {
      return wrapper.find(keyOrProps);
    } catch (e) {
      return null;
    }
  };
  wrapper.find = function (keyOrProps) {
    var _builtLogic$pathStrin;
    var builtLogic = typeof keyOrProps === 'object' || typeof keyOrProps === 'undefined' ? getCachedBuiltLogicByProps(wrapper, keyOrProps) : getCachedBuiltLogicByKey(wrapper, keyOrProps);
    if (builtLogic && getContext().mount.counter[builtLogic.pathString] > 0) {
      return builtLogic;
    }
    var keyString = typeof keyOrProps !== 'undefined' ? " with " + (typeof keyOrProps === 'object' ? 'props' : 'key') + " " + JSON.stringify(keyOrProps) : '';
    throw new Error("[KEA] Can not find mounted " + ((_builtLogic$pathStrin = builtLogic === null || builtLogic === void 0 ? void 0 : builtLogic.pathString) !== null && _builtLogic$pathStrin !== void 0 ? _builtLogic$pathStrin : 'logic') + keyString);
  };
  wrapper.extend = function (extendedInput) {
    var wrapperContext = getContext().wrapperContexts.get(wrapper);
    if (wrapperContext) {
      throw new Error("[KEA] Can not extend logic once it has been built.");
    }
    if (Array.isArray(extendedInput)) {
      wrapper.inputs = wrapper.inputs.concat(extendedInput);
    } else {
      wrapper.inputs.push(extendedInput);
    }
    return wrapper;
  };
  if (getContext().options.proxyFields) {
    proxyFields(wrapper);
  }
  return wrapper;
}
function proxyFieldToLogic(wrapper, key) {
  if (!wrapper.hasOwnProperty(key)) {
    Object.defineProperty(wrapper, key, {
      get: function get() {
        var logic = wrapper.findMounted();
        if (!logic && getContext().buildHeap.length > 0) {
          logic = wrapper.build();
        }
        if (logic) {
          return logic[key];
        } else {
          throw new Error(unmountedActionError(String(key), wrapper.build().pathString));
        }
      }
    });
  }
}
function proxyFields(wrapper) {
  var reservedProxiedKeys = ['path', 'pathString', 'props'];
  for (var _i = 0, _reservedProxiedKeys = reservedProxiedKeys; _i < _reservedProxiedKeys.length; _i++) {
    var key = _reservedProxiedKeys[_i];
    proxyFieldToLogic(wrapper, key);
  }
  for (var _i2 = 0, _Object$keys = Object.keys(getContext().plugins.logicFields); _i2 < _Object$keys.length; _i2++) {
    var _key = _Object$keys[_i2];
    proxyFieldToLogic(wrapper, _key);
  }
}
function unmountedActionError(key, path) {
  return "[KEA] Can not access \"" + key + "\" on logic \"" + path + "\" because it is not mounted!\nThis can happen in several situations:\n- You may need to add the \"connect(otherLogic)\" logic builder, or \"useMountedLogic(otherLogic)\" hook to make sure the logic is mounted.\n- If \"otherLogic\" is undefined, your bundler may import and execute code in an unfavourable order. Switch to a function: \"connect(() => otherLogic)\" \n- It may be that the logic has already unmounted. Do you have a listener that is missing a breakpoint?";
}

function getOrCreateContextForLogicWrapper(logic) {
  var context = getContext().react.contexts.get(logic);
  if (!context) {
    context = /*#__PURE__*/React__namespace.createContext(undefined);
    getContext().react.contexts.set(logic, context);
  }
  return context;
}
function BindLogic(_ref) {
  var logic = _ref.logic,
    props = _ref.props,
    children = _ref.children;
  var LogicContext = getOrCreateContextForLogicWrapper(logic);
  var builtLogic = logic(props);
  useMountedLogic(builtLogic);
  return /*#__PURE__*/React__namespace.createElement(LogicContext.Provider, {
    value: builtLogic
  }, children);
}

var warned = process.env.NODE_ENV === 'test';
function Provider(_ref) {
  var children = _ref.children;
  if (!warned) {
    console.warn("[KEA] <Provider> is now a no-op and should be removed. If you need it for Redux, use react-redux's <Provider store={getContext().store} />, or use Kea's useSelector.");
    warned = true;
  }
  return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, children);
}

var ATTACH_REDUCER = ATTACH_REDUCER$1;
var DETACH_REDUCER = DETACH_REDUCER$1;
resetContext({}, true);

exports.ATTACH_REDUCER = ATTACH_REDUCER;
exports.BindLogic = BindLogic;
exports.DETACH_REDUCER = DETACH_REDUCER;
exports.Provider = Provider;
exports.actions = actions;
exports.activatePlugin = activatePlugin;
exports.addConnection = addConnection;
exports.afterMount = afterMount;
exports.batchChanges = batchChanges;
exports.beforeUnmount = beforeUnmount;
exports.closeContext = closeContext;
exports.connect = connect;
exports.corePlugin = corePlugin;
exports.createActionCreator = createActionCreator;
exports.createStore = createStore;
exports.defaults = defaults;
exports.events = events;
exports.getContext = getContext;
exports.getPluginContext = getPluginContext;
exports.isBreakpoint = isBreakpoint;
exports.isBuiltLogic = isBuiltLogic;
exports.isLogicWrapper = isLogicWrapper;
exports.kea = kea;
exports.keaReducer = keaReducer;
exports.key = key;
exports.listeners = listeners;
exports.openContext = openContext;
exports.path = path;
exports.props = props;
exports.propsChanged = propsChanged;
exports.reducers = reducers;
exports.resetContext = resetContext;
exports.selectors = selectors;
exports.setPluginContext = setPluginContext;
exports.shallowCompare = shallowCompare;
exports.sharedListeners = sharedListeners;
exports.useActions = useActions;
exports.useAllValues = useAllValues;
exports.useAsyncActions = useAsyncActions;
exports.useMountedLogic = useMountedLogic;
exports.useSelector = useSelector;
exports.useValues = useValues;
